home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / share / pyshared / checkbox / user_interface.py < prev    next >
Encoding:
Python Source  |  2009-04-27  |  6.2 KB  |  178 lines

  1. #
  2. # This file is part of Checkbox.
  3. #
  4. # Copyright 2008 Canonical Ltd.
  5. #
  6. # Checkbox is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # Checkbox is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Checkbox.  If not, see <http://www.gnu.org/licenses/>.
  18. #
  19. import re
  20. import os
  21. import pwd
  22. import sys
  23. import logging
  24. import subprocess
  25. import webbrowser
  26.  
  27. import gettext
  28. from gettext import gettext as _
  29.  
  30. from checkbox.contrib.REThread import REThread
  31.  
  32. from checkbox.lib.environ import add_variable, get_variable, remove_variable
  33. from checkbox.lib.iterator import NEXT
  34.  
  35.  
  36. class UserInterface(object):
  37.     """Abstract base class for encapsulating the workflow and common code for
  38.        any user interface implementation (like GTK, Qt, or CLI).
  39.  
  40.        A concrete subclass must implement all the abstract show_* methods."""
  41.  
  42.     def __init__(self, title, data_path=None):
  43.         self.title = title
  44.         self.data_path = data_path
  45.  
  46.         self.direction = NEXT
  47.         self.gettext_domain = "checkbox"
  48.         gettext.textdomain(self.gettext_domain)
  49.  
  50.     def do_function(self, function, *args, **kwargs):
  51.         thread = REThread(target=function, name="do_function",
  52.             args=args, kwargs=kwargs)
  53.         thread.start()
  54.  
  55.         while thread.isAlive():
  56.             self.show_pulse()
  57.             thread.join(0.1)
  58.         thread.exc_raise()
  59.  
  60.         return thread.return_value()
  61.  
  62.     def show_error(self, title, text):
  63.         logging.error("%s: %s", title, text)
  64.  
  65.     def show_wait(self, message, function, *args, **kwargs):
  66.         self.do_function(function, *args, **kwargs)
  67.  
  68.     def show_pulse(self):
  69.         pass
  70.  
  71.     def show_intro(self, title, text):
  72.         raise NotImplementedError, \
  73.             "this function must be overridden by subclasses"
  74.  
  75.     def show_category(self, title, text, category):
  76.         raise NotImplementedError, \
  77.             "this function must be overridden by subclasses"
  78.  
  79.     def show_test(self, test, result):
  80.         raise NotImplementedError, \
  81.             "this function must be overridden by subclasses"
  82.  
  83.     def show_exchange(self, authentication, message=None):
  84.         raise NotImplementedError, \
  85.             "this function must be overridden by subclasses"
  86.  
  87.     def show_final(self, message):
  88.         raise NotImplementedError, \
  89.             "this function must be overridden by subclasses"
  90.  
  91.     def show_url(self, url):
  92.         """Open the given URL in a new browser window.
  93.  
  94.         Display an error dialog if everything fails."""
  95.  
  96.         (r, w) = os.pipe()
  97.         if os.fork() > 0:
  98.             os.close(w)
  99.             (pid, status) = os.wait()
  100.             if status:
  101.                 title = _("Unable to start web browser")
  102.                 error = _("Unable to start web browser to open %s." % url)
  103.                 message = os.fdopen(r).readline()
  104.                 if message:
  105.                     error += "\n" + message
  106.                 self.show_error(title, error)
  107.             try:
  108.                 os.close(r)
  109.             except OSError:
  110.                 pass
  111.             return
  112.  
  113.         os.setsid()
  114.         os.close(r)
  115.  
  116.         # If we are called through sudo, determine the real user id and run the
  117.         # browser with it to get the user's web browser settings.
  118.         try:
  119.             uid = int(get_variable("SUDO_UID"))
  120.             gid = int(get_variable("SUDO_GID"))
  121.             sudo_prefix = ["sudo", "-H", "-u", "#%s" % uid]
  122.         except (TypeError):
  123.             uid = os.getuid()
  124.             gid = None
  125.             sudo_prefix = []
  126.  
  127.         # figure out appropriate web browser
  128.         try:
  129.             # if ksmserver is running, try kfmclient
  130.             try:
  131.                 if os.getenv("DISPLAY") and \
  132.                         subprocess.call(["pgrep", "-x", "-u", str(uid), "ksmserver"],
  133.                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
  134.                     subprocess.call(sudo_prefix + ["kfmclient", "openURL", url])
  135.                     sys.exit(0)
  136.             except OSError:
  137.                 pass
  138.  
  139.             # if gnome-session is running, try gnome-open; special-case firefox
  140.             # (and more generally, mozilla browsers) and epiphany to open a new window
  141.             # with respectively -new-window and --new-window
  142.             try:
  143.                 if os.getenv("DISPLAY") and \
  144.                         subprocess.call(["pgrep", "-x", "-u", str(uid), "gnome-panel"],
  145.                                 stdout=subprocess.PIPE, stderr=subprocess.PIPE) == 0:
  146.                     gct = subprocess.Popen(sudo_prefix + ["gconftool", "--get",
  147.                         "/desktop/gnome/url-handlers/http/command"],
  148.                         stdout=subprocess.PIPE, stderr=subprocess.PIPE)
  149.                     if gct.returncode == 0:
  150.                         preferred_browser = gct.communicate()[0]
  151.                         browser = re.match("((firefox|seamonkey|flock)[^\s]*)", preferred_browser)
  152.                         if browser:
  153.                             subprocess.call(sudo_prefix + [browser.group(0), "-new-window", url])
  154.                             sys.exit(0)
  155.                         browser = re.match("(epiphany[^\s]*)", preferred_browser)
  156.                         if browser:
  157.                             subprocess.call(sudo_prefix + [browser.group(0), "--new-window", url])
  158.                             sys.exit(0)
  159.                     if subprocess.call(sudo_prefix + ["gnome-open", url]) == 0:
  160.                         sys.exit(0)
  161.             except OSError:
  162.                 pass
  163.  
  164.             # fall back to webbrowser
  165.             if uid and gid:
  166.                 os.setgroups([gid])
  167.                 os.setgid(gid)
  168.                 os.setuid(uid)
  169.                 remove_variable("SUDO_USER")
  170.                 add_variable("HOME", pwd.getpwuid(uid).pw_dir)
  171.  
  172.             webbrowser.open(url, new=True, autoraise=True)
  173.             sys.exit(0)
  174.  
  175.         except Exception, e:
  176.             os.write(w, str(e))
  177.             sys.exit(1)
  178.